import { reactive } from "vue";
// import { findAncestorSvg } from "@/utils";
const findAncestorSvg = (node, event) => {
  // 检测是否有参数传入
  if (!node) return null;

  // 如果只有一个参数
  if (node.target) {
    event = null;
    // 当前元素的 svg 包裹元素
    node = node.target.ownerSVGElement;
  }
  // 向上一直遍历，直到找到 svg 元素
  while (node.ownerSVGElement) {
    node = node.ownerSVGElement;
  }

  return node;
};

export default {
  name: "Drag",
  props: {
    width: Number,
    height: Number,
    resetOnStart: {
      type: Boolean,
      default: false,
    },
    onDragStart: Function,
    onDragMove: Function,
    onDragEnd: Function,
  },
  setup(props) {
    const { resetOnStart, onDragStart, onDragMove, onDragEnd } = props;
    const state = reactive({
      x: undefined,
      y: undefined,
      dx: 0,
      dy: 0,
      isDragging: false, // 鼠标按下
      isMoving: true, // 鼠标移动
    });

    const getPoint = (event) => {
      // 容器尺寸
      const bound = findAncestorSvg(event).getBoundingClientRect();
      const { clientX, clientY } = event;
      return {
        x: clientX - bound.left,
        y: clientY - bound.top,
      };
    }

    const dragStart = (event) => {
      // console.log(typeof onDragStart,111111111111112222)
      // console.log(props, this,111111111111112222)
      const point = getPoint(event);
      const nextState = {
        isDragging: true,
        isMoving: false,
        dx: resetOnStart ? 0 : state.dx,
        dy: resetOnStart ? 0 : state.dy,
        x: resetOnStart ? point.x : -state.dx + point.x,
        y: resetOnStart ? point.y : -state.dy + point.y,
      };
      Object.assign(state, nextState);
      if (typeof onDragStart === "function") onDragStart(nextState, event);
    }

    const dragMove = (event) => {
      if (!state.isDragging) return;
      const point = getPoint(event);
      // 避免无效移动
      if (Math.abs(point.x - state.x) < 2 && Math.abs(point.y - state.y) < 2)
        return;
      const nextState = {
        isDragging: true,
        isMoving: true,
        dx: point.x - state.x,
        dy: point.y - state.y,
      };
      Object.assign(state, nextState);
      if (typeof onDragMove === "function") onDragMove(state, event);
    }
    const dragEnd = (event) => {
      const nextState = {
        isDragging: false,
        isMoving: false,
      };
      const prevState = { ...state };
      Object.assign(state, nextState);
      // 传递 prevState
      if (typeof onDragEnd === "function")
        onDragEnd(state, event, {
          prevState,
        });
    }

    return {
      state,
      dragStart,
      dragMove,
      dragEnd,
      props
    };
  },

  render() {
    const children = this.$slots.default;
    // console.log(this.state.isDragging, 'children')
    return (
      <g>
        {this.state.isDragging && (
          <rect
            width={this.width}
            height={this.height}
            onMousemove={this.dragMove}
            onMouseup={this.dragEnd}
            fill="transparent"
          />
        )}
        {typeof children === "function" &&
          children({
            state: this.state,
            dragStart: this.dragStart,
            dragMove: this.dragMove,
            dragEnd: this.dragEnd,
          })}
      </g>
    );
  },
};
